package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.arpa.core.web.Result;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.cache.*;
import com.arpa.wms.common.util.LogisticsUtils;
import com.arpa.wms.domain.consts.*;
import com.arpa.wms.domain.dto.DeliveryDistributionDTO;
import com.arpa.wms.domain.dto.DeliveryItemDTO;
import com.arpa.wms.domain.dto.InventoryDTO;
import com.arpa.wms.domain.entity.*;
import com.arpa.wms.domain.enums.*;
import com.arpa.wms.domain.vo.*;
import com.arpa.wms.mapper.DeliveryDistributionMapper;
import com.arpa.wms.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.arpa.wms.domain.consts.NumConst.NUM_ZERO;

/**
 * <p>
 * 出货分配 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-08-07
 */
@Service
@Log4j2
public class DeliveryDistributionServiceImpl extends ServiceImpl<DeliveryDistributionMapper, DeliveryDistribution> implements IDeliveryDistributionService {

    @Autowired
    private IDeliveryItemService iDeliveryItemService;

    @Autowired
    private IInventoryRecordService iInventoryRecordService;

    @Autowired
    private IInventoryService iInventoryService;

    @Autowired
    private IDeliveryService iDeliveryService;

    @Autowired
    private LocationCache locationCache;

    @Autowired
    private UnitCache unitCache;

    @Autowired
    private GoodsUnitConversionCache goodsUnitConversionCache;

    @Autowired
    @Lazy
    private IPickingItemService pickingItemService;

    @Autowired
    @Lazy
    private IPickingService pickingService;

    @Autowired
    @Lazy
    private IPickingRegisterService pickingRegisterService;

    @Autowired
    @Lazy
    private IOutboundItemService outboundItemService;

    @Autowired
    @Lazy
    private IOutboundRegisterService outboundRegisterService;

    @Autowired
    @Lazy
    private IOutboundService outboundService;

    @Autowired
    private CustomerCache customerCache;

    @Autowired
    private GoodsCache goodsCache;

    @Autowired
    @Lazy
    private IWmsTaskService iWmsTaskService;

    @Autowired
    private PartyCache partyCache;

    @Autowired
    @Lazy
    private IOutboundService iOutboundService;

    @Autowired
    @Lazy
    private IPickingService iPickingService;

    @Autowired
    private ILocationService locationService;

    @Autowired
    @Lazy
    private IPrepackagedDistributionService prepackagedDistributionService;

    @Autowired
    private ILocationService iLocationService;

    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(DeliveryDistribution entity) {
        if(StringUtils.isBlank(entity.getCode())){
            entity.setCode(IdUtil.simpleUUID());
        }
        if(StringUtils.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
        }
        return super.save(entity);
    }

    /**
     * 分配的批量保存
     * @param deliveryItemVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result batchSave(DeliveryItemVO deliveryItemVO) {
        String groupCode = deliveryItemVO.getGroupCode();
        List<InventoryWithDistributionVO> temp = deliveryItemVO.getInventoryWithDistributionVOList();
        //　清除掉分配数量是空的
        List<InventoryWithDistributionVO> inventoryWithDistributionVoS = temp.stream().filter(e->
          e.getDistributionQuantity() != null && e.getDistributionQuantity().compareTo(BigDecimal.ZERO) > 0
        ).collect(Collectors.toList());
        // 如果没有分配的数据，则直接返回，不再处理
        if (IterUtil.isEmpty(inventoryWithDistributionVoS)) {
            return Result.ok();
        }

        // 判断总数是否超过待分配库存
        DeliveryItem deliveryItem = iDeliveryItemService.getOne(new QueryWrapper<DeliveryItem>().lambda().eq(DeliveryItem::getCode, deliveryItemVO.getCode()).eq(DeliveryItem::getGroupCode,groupCode));
        BigDecimal remainQuantity = deliveryItem.getTotalNum().subtract(deliveryItem.getDistributionQuantity());

        // 判断新增的分配数量是否超过允许数量
        BigDecimal newDistributionQuantity = inventoryWithDistributionVoS.stream().map(InventoryWithDistributionVO::getDistributionQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        if(newDistributionQuantity.compareTo(remainQuantity) > 0){
            return Result.error("分配数量超过剩余分配数量");
        }

        Delivery delivery = iDeliveryService.getOne(new QueryWrapper<Delivery>().lambda().eq(Delivery::getCode, deliveryItemVO.getDeliveryCode()).eq(Delivery::getGroupCode,groupCode));
        Inventory tempInventory;

        // 锁定库存
        for(InventoryWithDistributionVO e: inventoryWithDistributionVoS){
            UsefulInventoryVO usefulInv = new UsefulInventoryVO();
            BeanUtil.copyProperties(e, usefulInv);
            // 赋值基本单位信息
            usefulInv.setBasicUnit(e.getGoodsUnit());
            usefulInv.setBasicUnitName(e.getUnitName());
            DeliveryItem item = new DeliveryItem();
            BeanUtil.copyProperties(deliveryItemVO, item);
            // 生成分配单（有相同分配单的，更新相同分配单，没有则新增）
            DeliveryDistribution sameDistribution = insertOrUpdateDistribution(usefulInv, item, e.getDistributionQuantity());

            reduceInventory(sameDistribution, deliveryItem);

            // 用于分配的库存
            Inventory distributeInventory = new Inventory();
            // 临时库存增加
            BeanUtil.copyProperties(e, distributeInventory);
            tempInventory = saveDeliveryTempInventory(sameDistribution, delivery, deliveryItem, distributeInventory);

            // 临时库存标记作业状态、 添加库存日志
            iInventoryService.setTempInvJobStatusWorking(tempInventory.getCode());
            iInventoryRecordService.insertRecord(sameDistribution.getOldInventoryCode(), sameDistribution.getDeliveryCode(),
                    sameDistribution.getDistributionQuantity().negate(), InventoryRecordTypeEnum.PICK.getValue());
            iInventoryRecordService.insertRecord(tempInventory, sameDistribution.getDeliveryCode(),
                    sameDistribution.getDistributionQuantity(), InventoryRecordTypeEnum.PICK.getValue());

            // 需要回填发货分配的库存，将库存编码指向临时库存
            update(new UpdateWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getCode, sameDistribution.getCode())
                    .eq(DeliveryDistribution::getGroupCode,groupCode)
                    .set(DeliveryDistribution::getInventoryCode, tempInventory.getCode())   //新库存编码
                    .set(DeliveryDistribution::getOldInventoryCode,e.getCode()));   //旧的库存编码
        }

        // 更新明细上的分配数量
        DeliveryItemDTO deliveryItemDTO = new DeliveryItemDTO();
        deliveryItemDTO.setCode(deliveryItemVO.getCode());
        deliveryItemDTO.setDistributionQuantity(newDistributionQuantity);
        iDeliveryItemService.adjustDistributionQuantity(deliveryItemDTO);

        // 更新发货单分配数量
        BigDecimal newTotalDistributionQuantity = delivery.getDistributionNum().add(newDistributionQuantity);
        LambdaUpdateWrapper<Delivery> updateWrapper = new UpdateWrapper<Delivery>().lambda();
        updateWrapper.eq(Delivery::getCode, delivery.getCode()).eq(Delivery::getGroupCode,groupCode);
        updateWrapper.setSql(" distribution_num = distribution_num + " + newDistributionQuantity);
        if(delivery.getTotalNum().compareTo(newTotalDistributionQuantity) > 0) {
            // 总数未满，则更新为部分分配（分配数量为0的已在最上面过滤返回了）
            updateWrapper.set(Delivery::getStatus, DeliveryStatusEnum.PART_DISTRIBUTION.getValue());
            iDeliveryService.update(updateWrapper);
        }else{
            // 数量已满，则只更新数量，调用确认生成拣货单时会调整状态的
            iDeliveryService.update(updateWrapper);
            // 确认生成拣货单
            iDeliveryService.confirm(delivery.getCode(),groupCode);
        }

        return Result.ok();
    }


    /**
     * 根据发货单号查询带Item信息的分配信息列表
     * @param deliveryCode
     * @return
     */
    @Override
    public List<DeliveryItemWithDistributionVO> queryWithItemList(String deliveryCode) {
        return queryWithItemList(deliveryCode, null);
    }

    /**
     * 根据发货单号、拣货单号查询关联明细的分配信息列表
     * @param deliveryCode
     * @param pickingCode
     * @return
     */
    @Override
    public List<DeliveryItemWithDistributionVO> queryWithItemList(String deliveryCode, String pickingCode) {
        List<DeliveryItemWithDistributionVO> deliveryDistributionWithItemVoS = this.baseMapper.queryWithItemList(deliveryCode, pickingCode,UserUtil.getBranchCode());

        // 过滤、翻译
        deliveryDistributionWithItemVoS.stream().forEach(e->{
            e.setLocationName(locationCache.translate(e.getLocation()));
            e.setGoodsUnitName(unitCache.translate(e.getGoodsUnit()));
            e.setBasicUnitName(unitCache.translate(e.getBasicUnit()));
            List<GoodsUnitConversion> goodsUnitConversions = goodsUnitConversionCache.get(e.getGoodsCode());
            e.setGoodsUnitConversionList(goodsUnitConversions);
        });
        return deliveryDistributionWithItemVoS;
    }

    /**
     * 自动分配库存
     * @param deliveryCode
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Result autoDistribute(String deliveryCode) {
        String groupCode = UserUtil.getBranchCode();
        Delivery delivery = iDeliveryService.getOne(new QueryWrapper<Delivery>().lambda().eq(Delivery::getCode, deliveryCode).eq(Delivery::getGroupCode,groupCode));
        Integer isDeliveringIfStockout = delivery.getIsDeliveringIfStockout();
        InventoryDTO inventoryDTO;
        // 发货单新锁定数量
        BigDecimal totalNewLockQuantity = BigDecimal.ZERO;
        // 查询获取明细
        List<DeliveryItem> deliveryItems = iDeliveryItemService.list(new QueryWrapper<DeliveryItem>().lambda()
                            .eq(DeliveryItem::getDeliveryCode, deliveryCode).eq(DeliveryItem::getGroupCode, groupCode).eq(DeliveryItem::getDeleted, 0));
        //判断订单明细的商品编码和数量是否和预打包库位上的fastMatching相匹配
        List<Inventory> prepackagedInvList = matchPrepackagedInv(deliveryItems, delivery);
        //判断是否完全是自动分配
        boolean autoDistribute = delivery.getDistributionNum().compareTo(BigDecimal.ZERO) == 0;
        //完全自动分配和订单明细商品编码匹配预打包fastMatching字段时，先用预打包分配库存
        if (autoDistribute && IterUtil.isNotEmpty(prepackagedInvList)) {
            //订单分配预打包库存
            totalNewLockQuantity = prepackagedInvDistribute(prepackagedInvList,deliveryItems,totalNewLockQuantity,delivery);
            //根据库存获取预打包单号
         /*   PrepackagedDistribution prepackagedDistribution = prepackagedDistributionService.list(new LambdaQueryWrapper<PrepackagedDistribution>()
                    .select(PrepackagedDistribution::getPrepackagedCode)
                    .eq(PrepackagedDistribution::getInventoryCode, prepackagedInvList.get(NUM_ZERO).getOldInventoryCode())).get(NUM_ZERO);*/
            // 更新发货单分配数量和预打包标识
            iDeliveryService.update(new UpdateWrapper<Delivery>().lambda()
                    .eq(Delivery::getCode, deliveryCode)
                    .eq(Delivery::getGroupCode,groupCode)
                    .set(Delivery::getPrepackaged,NumConst.NUM_ONE)
                    .set(Delivery::getPackIssue,NumConst.NUM_ONE)
                    .setSql(" distribution_num = distribution_num + " + totalNewLockQuantity)
                    .set(Delivery::getPrepackagedCode,prepackagedInvList.get(NUM_ZERO).getTempCode()));
        } else {
            // 过滤掉已完全分配的明细，即保留明细总数-分配数量 >0的数据
            deliveryItems = deliveryItems.stream().filter(e->
                    e.getDistributionQuantity()!=null && e.getTotalNum().subtract(e.getDistributionQuantity()).compareTo(BigDecimal.ZERO) > 0
            ).collect(Collectors.toList());
            // 遍历这些待分配明细，获取库存，分配库存
            for(DeliveryItem deliveryItem: deliveryItems){
                inventoryDTO = new InventoryDTO();
                inventoryDTO.setWarehouseCode(delivery.getWarehouseCode());
                inventoryDTO.setShipmentCode(delivery.getShipmentCode());
                inventoryDTO.setGoodsCode(deliveryItem.getGoodsCode());
                inventoryDTO.setIsLock(NUM_ZERO);

                // 剩余待分配数量
                BigDecimal remainQuantity = deliveryItem.getTotalNum().subtract(deliveryItem.getDistributionQuantity());
                // 库存可用数量
                BigDecimal usefulQuantity;
                // 待锁定数量
                BigDecimal lockQuantity;
                // 明细新增待锁定数量
                BigDecimal totalItemNewLockQuantity = BigDecimal.ZERO;

                List<UsefulInventoryVO> inventories = iInventoryService.getCanAutoDistributedInventory(inventoryDTO,isDeliveringIfStockout);

                DeliveryDistribution distribution;
                Inventory distributeInventory = new Inventory();
                Inventory tempInventory;
                // 遍历获取明细，根据明细的总数-分配数量>0的即需要分配的
                if (IterUtil.isNotEmpty(inventories)) {
                    for(UsefulInventoryVO inventory: inventories){
                        usefulQuantity = inventory.getQuantity().subtract(inventory.getUseQuantity());
                        lockQuantity = usefulQuantity.compareTo(remainQuantity)>0?remainQuantity:usefulQuantity;
                        // 更新主子表新锁定数量
                        totalItemNewLockQuantity = totalItemNewLockQuantity.add(lockQuantity);
                        totalNewLockQuantity = totalNewLockQuantity.add(lockQuantity);

                        // 插入或更新分配表
                        distribution = insertOrUpdateDistribution(inventory, deliveryItem, lockQuantity);

                        // 减去库存
                        reduceInventory(distribution, deliveryItem);

                        BeanUtil.copyProperties(inventory, distributeInventory);
                        // 增加临时库存
                        tempInventory = saveDeliveryTempInventory(distribution, delivery, deliveryItem, distributeInventory);

                        // 临时库位中的库存作业状态改为工作中，避免其他操作使用
                        iInventoryService.setTempInvJobStatusWorking(tempInventory.getCode());

                        // 记录库存变动日志， 原库存减少，临时库存增加
                        iInventoryRecordService.insertRecord(distributeInventory, delivery.getCode(), distribution.getDistributionQuantity().negate(), InventoryRecordTypeEnum.PICK.getValue());
                        iInventoryRecordService.insertRecord(tempInventory, delivery.getCode(), distribution.getDistributionQuantity(), InventoryRecordTypeEnum.PICK.getValue());

                        // 需要回填发货分配的库存，将库存编码指向临时库存
                        update(new UpdateWrapper<DeliveryDistribution>().lambda()
                                .eq(DeliveryDistribution::getGroupCode,groupCode)
                                .eq(DeliveryDistribution::getCode, distribution.getCode())
                                .set(DeliveryDistribution::getInventoryCode, tempInventory.getCode())
                                .set(DeliveryDistribution::getOldInventoryCode,inventory.getCode())
                        );

                        // 更新剩余数量
                        remainQuantity = remainQuantity.subtract(lockQuantity);

                        // 剩余分配数量为0，则说明完成分配，提前退出循环
                        if(remainQuantity.compareTo(BigDecimal.ZERO) == 0){
                            break;
                        }
                    }
                }

                // 更新明细的分配数量
                if(totalItemNewLockQuantity.compareTo(BigDecimal.ZERO) > 0) {
                    DeliveryItemDTO deliveryItemDTO = new DeliveryItemDTO();
                    deliveryItemDTO.setCode(deliveryItem.getCode());
                    deliveryItemDTO.setDistributionQuantity(totalItemNewLockQuantity);
                    iDeliveryItemService.adjustDistributionQuantity(deliveryItemDTO);
                }
            }
            // 更新发货单分配数量
            iDeliveryService.update(new UpdateWrapper<Delivery>().lambda()
                    .eq(Delivery::getCode, deliveryCode).eq(Delivery::getGroupCode,groupCode)
                    .setSql(" distribution_num = distribution_num + " + totalNewLockQuantity));
        }

        delivery = iDeliveryService.getOne(new QueryWrapper<Delivery>().lambda().eq(Delivery::getCode, delivery.getCode()).eq(Delivery::getGroupCode,groupCode));

        // 如果发货单完全分配，则触发完全确认操作
        if (delivery.getTotalNum().compareTo(delivery.getDistributionNum()) == 0) {
            // 调用确认功能
            iDeliveryService.confirm(deliveryCode,groupCode);
        } else {
            // 如果数量不足，但有分配，则状态调整为部分分配
            if (delivery.getDistributionNum().compareTo(BigDecimal.ZERO) > 0) {
                iDeliveryService.update(new UpdateWrapper<Delivery>().lambda().eq(Delivery::getCode, delivery.getCode())
                        .eq(Delivery::getGroupCode,groupCode)
                        .set(Delivery::getStatus, DeliveryStatusEnum.PART_DISTRIBUTION.getValue()));
            }
        }

        return Result.ok();
    }

    /**
     * 根据分配表code， 调整分配数量，正数表示增加，负数表示减少
     * @param deliveryDistributionDTO
     * @return
     */
    @Override
    public int adjustDistributionQuantity(DeliveryDistributionDTO deliveryDistributionDTO) {
        return this.baseMapper.adjustDistributeQuantity(deliveryDistributionDTO);
    }

    /***
     * @description
     * 根据订单号，更新分配单拣货数量
     * @author xuyang
     * @date 2020/10/23 13:56
     * @param deliveryCode :
     **/
    @Override
    public int updatePickingQuantityForCheck(String deliveryCode,String groupCode) {
        return this.baseMapper.updatePickingQuantityForCheck(deliveryCode,groupCode);
    }

    /**
     * 查询是否有相同的分配信息
     *
     * @param itemCode
     * @param distributionCode
     * @return
     */
    @Override
    public DeliveryDistribution hasSameDistribution(String itemCode, String distributionCode) {
        // 根据明细code,获取其他分配信息
        List<DeliveryDistribution> otherDistributions = list(new QueryWrapper<DeliveryDistribution>().lambda()
                .eq(DeliveryDistribution::getDeliveryItemCode, itemCode).ne(DeliveryDistribution::getCode, distributionCode));
        if (IterUtil.isEmpty(otherDistributions)) {
            return null;
        }

        DeliveryDistribution distribution = getOne(new QueryWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getCode, distributionCode));
        // 判断是否有相同库存号且拣货单号是一样的数据
        otherDistributions = otherDistributions.stream().filter(e->e.getInventoryCode().equals(distribution.getInventoryCode())
                && StrUtil.equals(e.getPickingCode(), distribution.getPickingCode())).collect(Collectors.toList());
        if (IterUtil.isNotEmpty(otherDistributions)) {
            return otherDistributions.get(NumConst.NUM_ZERO);
        }

        return null;
    }

    /**
     * 插入或更新分配表，根据库存、分配明细、待锁定数量
     * @param inventory
     * @param deliveryItem
     * @param lockQuantity
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public DeliveryDistribution insertOrUpdateDistribution(UsefulInventoryVO inventory, DeliveryItem deliveryItem, BigDecimal lockQuantity){
        // 查询是否有相同分配数据且未生成拣货单，有则在起基础上增加，没有则插入一条新的
        DeliveryDistribution sameDistribution = this.getOne(new QueryWrapper<DeliveryDistribution>().lambda()
                .eq(DeliveryDistribution::getDeliveryItemCode, deliveryItem.getCode())
                .eq(DeliveryDistribution::getOldInventoryCode, inventory.getCode())
                .eq(DeliveryDistribution::getPickingCode, StrUtil.EMPTY)
                .eq(DeliveryDistribution::getDeleted, 0));
        if(sameDistribution == null){
            // 插入新的分配数据
            sameDistribution = new DeliveryDistribution();
            BeanUtil.copyProperties(inventory, sameDistribution);
            sameDistribution.setCode(IdUtil.simpleUUID());
            sameDistribution.setInventoryCode(inventory.getCode());
            sameDistribution.setGoodsUnit(deliveryItem.getGoodsUnit());
            sameDistribution.setGoodsUnitName(deliveryItem.getGoodsUnitName());
            sameDistribution.setDeliveryCode(deliveryItem.getDeliveryCode());
            sameDistribution.setDeliveryItemCode(deliveryItem.getCode());
            sameDistribution.setRemarks(deliveryItem.getRemarks());
            sameDistribution.setPickingCode(StrUtil.EMPTY);
            sameDistribution.setDistributionQuantity(lockQuantity);
            sameDistribution.setPlanQuantity(lockQuantity);
            sameDistribution.setOldInventoryCode(inventory.getCode());
            sameDistribution.setGroupCode(UserUtil.getBranchCode());
            sameDistribution.setInventoryContainerBarCode(inventory.getContainerBarCode());
            this.save(sameDistribution);
        }else{
            DeliveryDistributionDTO distributionDTO = new DeliveryDistributionDTO();
            distributionDTO.setCode(sameDistribution.getCode());
            distributionDTO.setDistributionQuantity(lockQuantity);
            distributionDTO.setPlanQuantity(lockQuantity);
            this.baseMapper.adjustDistributeQuantity(distributionDTO);
            //有相同的分配明细的特殊处理，只是为了第二次分配的时候，库存计算准确
            sameDistribution.setDistributionQuantity(lockQuantity);
            sameDistribution.setPlanQuantity(lockQuantity);

        }
        //分配跟动碰次数
        iLocationService.updateActionNum(sameDistribution.getLocation(), 1);

        return sameDistribution;
    }


    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(DeliveryDistribution entity) {
        if(StringUtils.isBlank(entity.getModifiedBy())){
            entity.setModifiedBy(UserUtil.getCode());
        }
        return baseMapper.update(entity,new QueryWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getCode,entity.getCode()).eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode()));
    }

    /**
     * 查询列表
     * @param deliveryDistributionDTO
     * @return
     */
    @Override
    public List<DeliveryDistributionVO> queryList(DeliveryDistributionDTO deliveryDistributionDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isNotEmpty(deliveryDistributionDTO.getSortField())){
            deliveryDistributionDTO.setSortField(CommonUtil.camel2Underline(deliveryDistributionDTO.getSortField()));
        }
        List<DeliveryDistributionVO> deliveryDistributionVOList = baseMapper.queryList(deliveryDistributionDTO);
        return deliveryDistributionVOList;
    }


    /**
     * 查询合计,包含总数
     * @param deliveryDistributionDTO
     * @return
     */
    @Override
    public DeliveryDistributionVO queryListSum(DeliveryDistributionDTO deliveryDistributionDTO){
        DeliveryDistributionVO deliveryDistributionVO = baseMapper.queryListSum(deliveryDistributionDTO);
        return deliveryDistributionVO;
    }



    /**
     * 分配时，保存分配临时库存信息
     * @param distribution
     * @param delivery
     * @param deliveryItem
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public Inventory saveDeliveryTempInventory(DeliveryDistribution distribution, Delivery delivery, DeliveryItem deliveryItem, Inventory inventory){
        // 库存变动量 = 分配数量
        BigDecimal changeQuantity = distribution.getDistributionQuantity();
        // 判断是否有相同的临时库存，如果有，则在其基础上增加数量，如果没有，则新增一条
        Inventory sameInventory = iInventoryService.hasSameDeliveryTempInventory(distribution, delivery);
        if(sameInventory == null){
            sameInventory = iInventoryService.saveDeliveryTempInventory(distribution, delivery, deliveryItem, inventory);
        }else{
            // 增加临时库存
            iInventoryService.adjustQuantity(sameInventory.getCode(), changeQuantity);
        }

        return sameInventory;
    }

    /**
     * 减少库存
     * @param distribution
     * @param deliveryItem
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public Result reduceInventory(DeliveryDistribution distribution, DeliveryItem deliveryItem){
        // 库存变动量 = 分配数量
        BigDecimal changeQuantity = distribution.getDistributionQuantity();

        // 原库存上扣除已分配的库存, 将变动量转为负数，用于减库存
        boolean flag = iInventoryService.reduceQuantity(distribution.getOldInventoryCode(), changeQuantity);
        if (!flag) {
            throw new ServiceException("分配数量超过了可用数量，无法分配");
        }
        return Result.ok();
    }

    /**
     * 根据code更新实体，拣货单明细及拣货单数量
     * @param entities
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public List<PickingRegister> updateDeliveryDistributions(List<DeliveryDistribution> entities,boolean isUsePda,String wavePickingCode,String inventoryCode) {
        //判断缺货登记的状态是否已拣货，已拣货的不能进行缺货登记
        PickingRegister register = pickingRegisterService.getOne(new QueryWrapper<PickingRegister>().lambda()
                .eq(PickingRegister::getGroupCode,UserUtil.getBranchCode())
                .eq(PickingRegister::getWavePickingCode, wavePickingCode).eq(PickingRegister::getInventoryCode, inventoryCode));
        log.info("拣货缺货登记，拣货明细:{}", JSONUtil.toJsonStr(register));
        if (PickingStatusEnum.FINISH_PICK.getValue().equals(register.getStatus())) {
            throw new ServiceException(TipConst.THE_GOODS_HAS_PICKED_CAN_NOT_STOCK_OUT);
        }
        BigDecimal totalPickingQuantity = BigDecimal.ZERO;
        //数量校验
        validateData(entities,isUsePda);
        for (DeliveryDistribution entity : entities) {
            if(StringUtils.isBlank(entity.getCode())){
                throw new ServiceException(TipConst.CODE_NOT_EMPTY);
            }
            BigDecimal refundQuantity;
            BigDecimal pickingQuantity;
            if (isUsePda) {
                refundQuantity = entity.getDistributionQuantity().subtract(entity.getPickingQuantity());
                pickingQuantity = entity.getPickingQuantity();
            } else {
                refundQuantity = entity.getRefundQuantity();
                pickingQuantity = entity.getDistributionQuantity().subtract(entity.getRefundQuantity());
            }
            totalPickingQuantity = totalPickingQuantity.add(pickingQuantity);
            //更新分配单的缺货数量
            this.update(new UpdateWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getCode, entity.getCode()).set(DeliveryDistribution::getPickStockOutNum, refundQuantity).eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode()));
            //更新分配表、拣货单明细表，拣货单表
            updateStockoutInfo(refundQuantity,pickingQuantity,entity.getCode());


        }
        //更新拣货单状态
        updatePickingStatus(wavePickingCode);
        //处理订单完全缺货
        handleWholeStockOutDelivery(wavePickingCode,PropertyConst.PICKING);

        // 尝试触发主单拣货完成逻辑
        String pickingCode = register.getPickingCode();
        int finishPickingFlag = pickingService.updateStatusIfFinish(pickingCode, PickingStatusEnum.FINISH_PICK.getValue());
        if (finishPickingFlag == NumConst.NUM_ZERO) {
            // 如果整个单子没完成，则将任务设置为作业中
            iWmsTaskService.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, pickingCode)
                    .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.WORKING)
                    .setSql(" job_quantity = job_quantity + " + totalPickingQuantity)
                    .set(WmsTask::getOperatorBy, UserUtil.getCode())
                    .set(WmsTask::getOperatorName, partyCache.translate(UserUtil.getCode())));
            // 更新主单为拣货中状态
            pickingService.update(new UpdateWrapper<Picking>().lambda().eq(Picking::getCode, pickingCode).set(Picking::getStatus, PickingStatusEnum.PICKING.getValue()));
        }
        //缺货登记执行到最后一条时，触发批量拣货确认操作
        List<String> registerStatuses = new ArrayList<>(Arrays.asList(PickingStatusEnum.NOT_PICK.getValue(), PickingStatusEnum.PICKING.getValue()));
        List<PickingRegister> registerList = pickingRegisterService.list(new QueryWrapper<PickingRegister>().lambda()
                .eq(PickingRegister::getWavePickingCode, wavePickingCode).in(PickingRegister::getStatus,registerStatuses)
                .eq(PickingRegister::getDeleted, NumConst.NUM_ZERO));
        return registerList;
    }

    /**
     * 根据code更新实体，拣货单明细及拣货单数量
     *
     * @param entities
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public List<PickingRegister> updateDeliveryDistributionsByLocation(List<DeliveryDistribution> entities,String wavePickingCode, String location){
        boolean isUsePDA = true;
        String groupCode = UserUtil.getBranchCode();
        //判断缺货登记的状态是否已拣货，已拣货的不能进行缺货登记
        List<PickingRegister> registers = pickingRegisterService.list(new QueryWrapper<PickingRegister>().lambda()
                .eq(PickingRegister::getWavePickingCode, wavePickingCode)
                .eq(PickingRegister::getGroupCode, groupCode)
                .eq(PickingRegister::getLocation, location));
        if (IterUtil.isEmpty(registers)) {
            log.error("拣货登记信息不能为空");
            throw new ServiceException("拣货登记信息不能为空");
        }
        PickingRegister register = registers.get(NUM_ZERO);
        log.info("拣货缺货登记，拣货明细:{}", JSONUtil.toJsonStr(registers));
        if (PickingStatusEnum.FINISH_PICK.getValue().equals(register.getStatus())) {
            throw new ServiceException(TipConst.THE_GOODS_HAS_PICKED_CAN_NOT_STOCK_OUT);
        }
        BigDecimal totalPickingQuantity = BigDecimal.ZERO;
        //数量校验
        validateData(entities,true);
        for (DeliveryDistribution entity : entities) {
            if(StringUtils.isBlank(entity.getCode())){
                throw new ServiceException(TipConst.CODE_NOT_EMPTY);
            }
            BigDecimal refundQuantity;
            BigDecimal pickingQuantity;
            if (isUsePDA) {
                refundQuantity = entity.getDistributionQuantity().subtract(entity.getPickingQuantity());
                pickingQuantity = entity.getPickingQuantity();
            } else {
                refundQuantity = entity.getRefundQuantity();
                pickingQuantity = entity.getDistributionQuantity().subtract(entity.getRefundQuantity());
            }
            totalPickingQuantity = totalPickingQuantity.add(pickingQuantity);
            //更新分配单的缺货数量
            this.update(new UpdateWrapper<DeliveryDistribution>().lambda()
                    .eq(DeliveryDistribution::getCode, entity.getCode())
                    .set(DeliveryDistribution::getPickStockOutNum, refundQuantity));
            //更新分配表、拣货单明细表，拣货单表
            updateStockoutInfo(refundQuantity,pickingQuantity,entity.getCode());


        }
        //更新拣货单状态
        updatePickingStatus(wavePickingCode);
        //处理订单完全缺货
        handleWholeStockOutDelivery(wavePickingCode,PropertyConst.PICKING);

        // 尝试触发主单拣货完成逻辑
        String pickingCode = register.getPickingCode();
        int finishPickingFlag = pickingService.updateStatusIfFinish(pickingCode, PickingStatusEnum.FINISH_PICK.getValue());
        if (finishPickingFlag == NumConst.NUM_ZERO) {
            // 如果整个单子没完成，则将任务设置为作业中
            iWmsTaskService.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, pickingCode)
                    .eq(WmsTask::getGroupCode,groupCode)
                    .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.WORKING)
                    .setSql(" job_quantity = job_quantity + " + totalPickingQuantity)
                    .set(WmsTask::getOperatorBy, UserUtil.getCode())
                    .set(WmsTask::getOperatorName, partyCache.translate(UserUtil.getCode())));
            // 更新主单为拣货中状态
            pickingService.update(new UpdateWrapper<Picking>().lambda()
                    .eq(Picking::getCode, pickingCode)
                    .eq(Picking::getGroupCode,groupCode)
                    .set(Picking::getStatus, PickingStatusEnum.PICKING.getValue()));
        }
        //缺货登记执行到最后一条时，触发批量拣货确认操作
        List<String> registerStatuses = new ArrayList<>(Arrays.asList(PickingStatusEnum.NOT_PICK.getValue(), PickingStatusEnum.PICKING.getValue()));
        List<PickingRegister> registerList = pickingRegisterService.list(new QueryWrapper<PickingRegister>().lambda()
                .eq(PickingRegister::getWavePickingCode, wavePickingCode)
                .eq(PickingRegister::getGroupCode,groupCode)
                .in(PickingRegister::getStatus,registerStatuses)
                .eq(PickingRegister::getDeleted, NumConst.NUM_ZERO));
        return registerList;
    }





    private void validateData(List<DeliveryDistribution> entities,boolean isUsePda) {

        //pc端缺货数据检验
        if (!isUsePda) {
            for (DeliveryDistribution entity : entities) {
                //如果缺货数量大于分配数量，抛出异常
                if (null == entity.getRefundQuantity()) {
                    entity.setRefundQuantity(BigDecimal.ZERO);
                }
                if (entity.getRefundQuantity().compareTo(entity.getDistributionQuantity()) > NumConst.NUM_ZERO) {
                    throw new ServiceException("缺货数量不能大于分配数量！！！");
                }
                //缺货数量不能为负数
                if (entity.getRefundQuantity().compareTo(BigDecimal.ZERO) < NumConst.NUM_ZERO) {
                    throw new ServiceException("缺货数量不能为负数！！！");
                }
            }
        }
        if (isUsePda) {
            for (DeliveryDistribution entity : entities) {
                //如果拣货数量大于分配数量（待拣货数量），抛出异常
                if (entity.getPickingQuantity().compareTo(entity.getDistributionQuantity()) > NumConst.NUM_ZERO) {
                    throw new ServiceException("拣货数量不能大于待拣货数量！！！");
                }
                //拣货数量不能为负数
                if (entity.getPickingQuantity().compareTo(BigDecimal.ZERO) < NumConst.NUM_ZERO) {
                    throw new ServiceException("拣货数量不能为负数！！！");
                }
            }
        }
    }
    /**
     * 更新缺货信息
     * @date 2021/4/19 10:59
     * @param refundQuantity 缺货数量
     * @param pickingQuantity 拣货数量
     * @param deliveryDistributionCode 订单分配明细code
     */
    @Transactional(rollbackFor = {Exception.class})
    public void updateStockoutInfo(BigDecimal refundQuantity,BigDecimal pickingQuantity,String deliveryDistributionCode) {
        DeliveryDistribution deliveryDistribution = this.getOne(new QueryWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode())
                .eq(DeliveryDistribution::getCode, deliveryDistributionCode).eq(DeliveryDistribution::getDeleted, NumConst.NUM_ZERO));
        if (null==deliveryDistribution) {
            log.error("缺货登记，订单分配明细找不到：{}",deliveryDistributionCode);
            throw new ServiceException("订单分配明细找不到");
        }
        //拣货波次号
        String wavePickingCode = deliveryDistribution.getWavePickingCode();
        String inventoryCode = deliveryDistribution.getInventoryCode();
        String oldInventoryCode = deliveryDistribution.getOldInventoryCode();

        log.info("拣货单：{}，缺货登记，获取订单分配明细信息：{}",wavePickingCode,JSONUtil.toJsonStr(deliveryDistribution));
        ////是否跳过复核
        //Picking picking = pickingService.getOne(new LambdaQueryWrapper<Picking>().eq(Picking::getWavePickingCode,wavePickingCode));
        //log.info("拣货单：{}，缺货登记，拣货单信息：{}",wavePickingCode,JSONUtil.toJsonStr(picking));


        //更新分配单信息
        if (deliveryDistribution.getDistributionQuantity().compareTo(refundQuantity)<NumConst.NUM_ZERO) {
            log.error("拣货单：{}，缺货登记，退拣数量不能超过分配数量。分配数量：{}，退捡数量：{}",wavePickingCode,deliveryDistribution.getDistributionQuantity(),refundQuantity);
            throw new ServiceException("退拣数量不能超过分配数量！！！");
        }

        boolean bool = this.update(new UpdateWrapper<DeliveryDistribution>().lambda()
                .eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode())
                .eq(DeliveryDistribution::getCode, deliveryDistributionCode)
                .setSql(SqlConst.DISTRIBUTION_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY + refundQuantity.negate())
                .set(DeliveryDistribution::getPickingQuantity,pickingQuantity)
                .set(refundQuantity.compareTo(BigDecimal.ZERO)>0, DeliveryDistribution::getDistributionStatus,DeliveryStatusEnum.PART_DISTRIBUTION.getValue()));
        log.info("拣货单：{}，缺货登记，更新订单分配明细：{}，退拣数量：{}，拣货数量：{}，结果：{}",wavePickingCode,deliveryDistributionCode,refundQuantity,pickingQuantity,bool);
        if(!bool){
            throw new ServiceException("缺货登记，更新订单分配明细失败");
        }

        //更新发货单明细
       bool = iDeliveryItemService.update(new UpdateWrapper<DeliveryItem>().lambda().eq(DeliveryItem::getCode, deliveryDistribution.getDeliveryItemCode())
               .eq(DeliveryItem::getGroupCode,UserUtil.getBranchCode())
                .eq(DeliveryItem::getDeleted, NumConst.NUM_ZERO)
                .setSql(SqlConst.DISTRIBUTION_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY + refundQuantity.negate())
                .setSql(SqlConst.PICKING_QUANTITY_EQUALS_PICKING_QUANTITY+pickingQuantity)
                .setSql("pick_stock_out_num = pick_stock_out_num+ "+refundQuantity)
                .set(refundQuantity.compareTo(BigDecimal.ZERO)>NumConst.NUM_ZERO, DeliveryItem::getStatus,DeliveryStatusEnum.PART_DISTRIBUTION.getValue()));

        log.info("拣货单：{}，缺货登记，更新订单明细{}，退拣数量：{}，拣货数量：{}，结果：{}",wavePickingCode,deliveryDistribution.getDeliveryItemCode(),refundQuantity,pickingQuantity,bool);
        if(!bool){
            throw new ServiceException("缺货登记，更新订单明细失败");
        }

        bool = iDeliveryService.update(new UpdateWrapper<Delivery>().lambda().eq(Delivery::getCode, deliveryDistribution.getDeliveryCode()).eq(Delivery::getGroupCode,UserUtil.getBranchCode())
                .eq(Delivery::getDeleted, NumConst.NUM_ZERO).setSql(SqlConst.DISTRIBUTION_NUM_EQUALS_DISTRIBUTION_NUM+refundQuantity.negate())
                .setSql(SqlConst.PICK_NUM_EQUALS_PICK_NUM+pickingQuantity)
                .setSql("pick_stock_out_num = pick_stock_out_num+ "+refundQuantity));

        //每次进行缺货登记的时候，都要尝试根据订单的计划数量与（订单的拣货数量和缺货数量之间的关系）
        Delivery delivery = iDeliveryService.getOne(new QueryWrapper<Delivery>().lambda().eq(Delivery::getCode, deliveryDistribution.getDeliveryCode()).eq(Delivery::getGroupCode,UserUtil.getBranchCode()));
        iDeliveryService.updateDelvieryStatus(delivery);

        log.info("拣货单：{}，缺货登记，更新订单{}，退拣数量：{}，拣货数量：{}，结果：{}",wavePickingCode,deliveryDistribution.getDeliveryCode(),refundQuantity,pickingQuantity,bool);
        if(!bool){
            throw new ServiceException("缺货登记，更新订单【"+deliveryDistribution.getDeliveryCode()+"】失败");
        }
        //更新拣货明细中的信息
        bool = pickingItemService.update(new UpdateWrapper<PickingItem>().lambda().eq(PickingItem::getWavePickingCode, wavePickingCode)
                .eq(PickingItem::getOldInventoryCode, oldInventoryCode)
                .eq(PickingItem::getGroupCode,UserUtil.getBranchCode())
                .setSql(SqlConst.DISTRIBUTION_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY + refundQuantity.negate())
                .setSql(SqlConst.PICKING_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY)
                .set(PickingItem::getStatus, PickingStatusEnum.FINISH_PICK.getValue())
                .set(PickingItem::getStockoutQuantity, refundQuantity));
        log.info("拣货单：{}，缺货登记，更新拣货明细拣货完成，缺货数量：{}，库存编码：{}，结果：{}",wavePickingCode,refundQuantity,inventoryCode,bool);
        //更新拣货确认中的信息
        bool = pickingRegisterService.update(new UpdateWrapper<PickingRegister>().lambda()
                .eq(PickingRegister::getWavePickingCode, wavePickingCode)
                .eq(PickingRegister::getOldInventoryCode, oldInventoryCode)
                .eq(PickingRegister::getGroupCode,UserUtil.getBranchCode())
                .setSql(SqlConst.DISTRIBUTION_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY + refundQuantity.negate())
                .setSql(SqlConst.PICKING_QUANTITY_EQUALS_DISTRIBUTION_QUANTITY)
                .set(PickingRegister::getNotPickingQuantity,BigDecimal.ZERO)
                .set(PickingRegister::getStatus,PickingStatusEnum.FINISH_PICK.getValue()));
        log.info("拣货单：{}，缺货登记，更新拣货确认完成，缺货数量：{}，库存编码：{}，结果：{}",wavePickingCode,refundQuantity,inventoryCode,bool);

        //更新拣货明主单的信息
        bool = pickingService.update(new UpdateWrapper<Picking>().lambda().eq(Picking::getWavePickingCode, wavePickingCode)
                .eq(Picking::getGroupCode,UserUtil.getBranchCode())
                .setSql(SqlConst.STOCKOUT_QUANTITY_EQUALS_STOCKOUT_QUANTITY + refundQuantity));
        log.info("拣货单：{}，缺货登记，更新拣货单缺货数量，缺货数量：{}，结果：{}",wavePickingCode,refundQuantity,bool);
        pickingService.updatePickingByPickingRegister(wavePickingCode);
        if (refundQuantity.compareTo(BigDecimal.ZERO) > 0) {
            //更新临时库存
            iInventoryService.stockoutInventory(inventoryCode, refundQuantity, StockoutTypeEnum.PICKING.getValue(), deliveryDistribution.getPickingCode());
        }
    }

    /**
     * 复核缺货
     * @param entitys
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public Result recheckStockOut(List<DeliveryDistribution> entitys,String wavePickingCode,String inventoryCode,boolean isUsePda) {
        //判断缺货登记的状态是否已复核，已复核的不能进行缺货登记
        OutboundRegister register = outboundRegisterService.getOne(new QueryWrapper<OutboundRegister>().lambda()
                .eq(OutboundRegister::getGroupCode,UserUtil.getBranchCode())
                .eq(OutboundRegister::getWavePickingCode, wavePickingCode).eq(OutboundRegister::getInventoryCode, inventoryCode));
        if (OutboundStatusEnum.NOT_OUT.getValue().equals(register.getStatus())) {
            throw new ServiceException(TipConst.THE_GOODS_HAS_RECHECKED_CAN_NOT_RECHECK_STOCK_OUT);
        }
        //数量校验
        validateRecheckData(entitys,isUsePda);
        for (DeliveryDistribution entity : entitys) {
            if(StringUtils.isBlank(entity.getCode())){
                return Result.error(TipConst.CODE_NOT_EMPTY);
            }

            BigDecimal recheckrefundQuantity;
            BigDecimal recheckQuantity = BigDecimal.ZERO;
            if (isUsePda) {
                recheckrefundQuantity = entity.getPickingQuantity().subtract(entity.getRecheckQuantity());
                recheckQuantity = entity.getRecheckQuantity();
            } else {
                recheckrefundQuantity = entity.getRecheckRefundQuantity();
                //未复核时，复核数量为拣货刷量与复核缺货数量之差
                if (OutboundStatusEnum.NOT_RECHECK.getValue().equals(register.getStatus())) {
                    recheckQuantity = entity.getPickingQuantity().subtract(entity.getRecheckRefundQuantity());
                }
                //复核中时，复核数量为拣货刷量与复核缺货数量之差，然后再加上已经复核的复核数量
                if (OutboundStatusEnum.RECHECKING.getValue().equals(register.getStatus())) {
                    recheckQuantity = entity.getPickingQuantity().subtract(entity.getRecheckRefundQuantity().add(entity.getRecheckQuantity()));
                }

            }
            if (entity.getPickingQuantity().compareTo(recheckrefundQuantity)<NumConst.NUM_ZERO) {
                throw new ServiceException("复核退货数量不能超过拣货数量！！！");
            }
            //更新订单和出库单的复核数量
            updateDeliveryAndOutboundRecheckQuantity(recheckrefundQuantity,recheckQuantity,entity.getCode());
        }
        //更新复核状态
        updateOutboundStatus(wavePickingCode);
        //处理订单完全缺货
        handleWholeStockOutDelivery(wavePickingCode,PropertyConst.OUT_BOUND);
        List<OutboundRegister> registerList ;
        if (isUsePda) {
            List<String> outboundRegisterStatusList = new ArrayList<>();
            outboundRegisterStatusList.add(OutboundStatusEnum.NOT_RECHECK.getValue());
            outboundRegisterStatusList.add(OutboundStatusEnum.RECHECKING.getValue());
            //缺货登记执行到最后一条时，触发批量复核确认操作
            registerList = outboundRegisterService.list(new QueryWrapper<OutboundRegister>().lambda().eq(OutboundRegister::getWavePickingCode, wavePickingCode)
                    .eq(OutboundRegister::getGroupCode,UserUtil.getBranchCode())
                    .in(OutboundRegister::getStatus, outboundRegisterStatusList).eq(OutboundRegister::getDeleted, NumConst.NUM_ZERO));
        } else {
            //缺货登记执行到最后一条时，触发批量复核确认操作
            registerList = outboundRegisterService.list(new QueryWrapper<OutboundRegister>().lambda().eq(OutboundRegister::getWavePickingCode, wavePickingCode)
                    .eq(OutboundRegister::getGroupCode,UserUtil.getBranchCode())
                    .eq(OutboundRegister::getStatus, OutboundStatusEnum.NOT_RECHECK.getValue()).eq(OutboundRegister::getDeleted, NumConst.NUM_ZERO));
        }

        if (IterUtil.isEmpty(registerList)) {
            //批量复核确认
            OutboundVO outboundVO = outboundService.getVOWithRegisterByCode(register.getOutboundCode());
            outboundService.batchRecheck(outboundVO);
            //更新任务状态
            iWmsTaskService.update(new UpdateWrapper<WmsTask>().lambda().eq(WmsTask::getSourceCode, register.getOutboundCode())
                    .eq(WmsTask::getGroupCode,UserUtil.getBranchCode())
                    .set(WmsTask::getJobStatus, WmsTaskJobStatusEnum.COMPLETED));

        }
        return Result.ok();
    }

    private void updateDeliveryAndOutboundRecheckQuantity (BigDecimal recheckrefundQuantity,BigDecimal recheckQuantity,String distributionCode ) {
        this.update(new UpdateWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getCode, distributionCode).set(DeliveryDistribution::getRecheckRefundQuantity, recheckrefundQuantity).eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode()));
        DeliveryDistribution deliveryDistribution = this.getOne(new QueryWrapper<DeliveryDistribution>().lambda()
                .eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode())
                .eq(DeliveryDistribution::getCode, distributionCode).eq(DeliveryDistribution::getDeleted, NumConst.NUM_ZERO));
        //更新发货主单
        iDeliveryService.update(new UpdateWrapper<Delivery>().lambda().eq(Delivery::getCode, deliveryDistribution.getDeliveryCode())
                .eq(Delivery::getDeleted, NumConst.NUM_ZERO)
                .eq(Delivery::getGroupCode,UserUtil.getBranchCode())
                .setSql("recheck_quantity=recheck_quantity+" + recheckQuantity)
                .setSql("recheck_refund_quantity = recheck_refund_quantity +"+recheckrefundQuantity)
                .set(Delivery::getStatus,DeliveryStatusEnum.UN_DELIVERY));
        //更新发货明细的复核数量
        iDeliveryItemService.update(new UpdateWrapper<DeliveryItem>().lambda().eq(DeliveryItem::getCode, deliveryDistribution.getDeliveryItemCode())
                .eq(DeliveryItem::getGroupCode,UserUtil.getBranchCode()).eq(DeliveryItem::getDeleted, NumConst.NUM_ZERO)
                .setSql("recheck_quantity=recheck_quantity+" + recheckQuantity));
        //更新出库明细中的信息
        outboundItemService.update(new UpdateWrapper<OutboundItem>().lambda().eq(OutboundItem::getWavePickingCode, deliveryDistribution.getWavePickingCode())
                .eq(OutboundItem::getOldInventoryCode, deliveryDistribution.getOldInventoryCode())
                .eq(OutboundItem::getGroupCode,UserUtil.getBranchCode())
                .setSql("recheck_refund_quantity = recheck_refund_quantity +" + recheckrefundQuantity)
                .setSql("return_quantity = recheck_refund_quantity")
                .setSql("recheck_quantity=recheck_quantity+"+recheckQuantity)
                .set(OutboundItem::getStatus,OutboundStatusEnum.NOT_OUT.getValue()));
        //更新出库确认中的信息
        outboundRegisterService.update(new UpdateWrapper<OutboundRegister>().lambda().eq(OutboundRegister::getWavePickingCode, deliveryDistribution.getWavePickingCode())
                .eq(OutboundRegister::getOldInventoryCode, deliveryDistribution.getOldInventoryCode())
                .eq(OutboundRegister::getGroupCode,UserUtil.getBranchCode())
                .setSql("recheck_refund_quantity=recheck_refund_quantity+" + recheckrefundQuantity)
                .setSql("recheck_quantity=recheck_quantity +" + recheckQuantity)
                .set(OutboundRegister::getStatus,OutboundStatusEnum.NOT_OUT.getValue()));
        //更新出库主单的信息
        OutboundItem outboundItem = outboundItemService.getOne(new QueryWrapper<OutboundItem>().lambda().eq(OutboundItem::getWavePickingCode, deliveryDistribution.getWavePickingCode())
                .eq(OutboundItem::getOldInventoryCode, deliveryDistribution.getOldInventoryCode()).eq(OutboundItem::getGroupCode,UserUtil.getBranchCode()));
        outboundService.update(new UpdateWrapper<Outbound>().lambda().eq(Outbound::getCode, outboundItem.getOutboundCode())
                .eq(Outbound::getGroupCode,UserUtil.getBranchCode())
                .setSql("recheck_refund_quantity = recheck_refund_quantity +" + recheckrefundQuantity)
                .setSql("return_quantity = recheck_refund_quantity")
                .setSql("recheck_quantity=recheck_quantity+"+recheckQuantity));
        //更新临时库存
        if (recheckrefundQuantity.compareTo(BigDecimal.ZERO) > 0) {
            //更新临时库存
            iInventoryService.stockoutInventory(deliveryDistribution.getInventoryCode(), recheckrefundQuantity, StockoutTypeEnum.OUT_CHECK.getValue(), deliveryDistribution.getPickingCode());
        }

    }

    private void validateRecheckData(List<DeliveryDistribution> entitys,boolean isUsePda) {

        //pc端缺货数据检验
        if (!isUsePda) {
            for (DeliveryDistribution entity : entitys) {
                if (ObjectUtil.isNull(entity.getRecheckRefundQuantity())) {
                    entity.setRecheckRefundQuantity(BigDecimal.ZERO);
                }
                //如果缺货数量大于分配数量，抛出异常
                if (entity.getRecheckRefundQuantity().compareTo(entity.getNotRecheckQuantity()) > NumConst.NUM_ZERO) {
                    throw new ServiceException("缺货数量不能大于复核数量！！！");
                }
                //缺货数量不能为负数
                if (entity.getRecheckRefundQuantity().compareTo(BigDecimal.ZERO) < NumConst.NUM_ZERO) {
                    throw new ServiceException("复核缺货数量不能为负数！！！");
                }
            }
        }
        if (isUsePda) {
            for (DeliveryDistribution entity : entitys) {
                //如果拣货数量大于分配数量（待拣货数量），抛出异常
                if (entity.getRecheckQuantity().compareTo(entity.getPickingQuantity()) > NumConst.NUM_ZERO) {
                    throw new ServiceException("复核数量不能大于待复核数量！！！");
                }
                //拣货数量不能为负数
                if (entity.getRecheckQuantity().compareTo(BigDecimal.ZERO) < NumConst.NUM_ZERO) {
                    throw new ServiceException("复核数量不能为负数！！！");
                }
            }
        }
    }

    /**
     * 根据库存编码获取出货分配 列表
     *
     * @param query
     * @return
     */
    @Override
    public List<DeliveryDistributionVO> queryListByInventoryCode(DeliveryDistributionDTO query,String source) {
        if (PropertyConst.PICKING.equals(source)) {
            //拣货确认单状态检验，如果拣货完成，不能执行缺货登记操作
            PickingRegister register = pickingRegisterService.getOne(new QueryWrapper<PickingRegister>().lambda().eq(PickingRegister::getWavePickingCode, query.getWavePickingCode())
                    .eq(PickingRegister::getGroupCode,UserUtil.getBranchCode()).eq(PickingRegister::getInventoryCode, query.getInventoryCode()));
            if (PickingStatusEnum.FINISH_PICK.getValue().equals(register.getStatus())) {
                throw new ServiceException(TipConst.THE_GOODS_HAS_PICKED_CAN_NOT_STOCK_OUT);
            }
        }
        if (PropertyConst.OUT_BOUND.equals(source)) {
            //复核确认单状态检验，如果复核完成，不能执行缺货登记操作
            List<OutboundRegister> registerList = outboundRegisterService.list(new QueryWrapper<OutboundRegister>().lambda()
                    .eq(OutboundRegister::getGroupCode,UserUtil.getBranchCode())
                    .eq(OutboundRegister::getWavePickingCode, query.getWavePickingCode())
                    .eq(OutboundRegister::getInventoryCode, query.getInventoryCode()));
            for (OutboundRegister outboundRegister : registerList) {
                if (OutboundStatusEnum.NOT_OUT.getValue().equals(outboundRegister.getStatus())) {
                    throw new ServiceException(TipConst.THE_GOODS_HAS_RECHECKED_CAN_NOT_RECHECK_STOCK_OUT);
                }
            }
        }
        DeliveryDistributionDTO deliveryDistributionDTO = new DeliveryDistributionDTO();
        deliveryDistributionDTO.setWavePickingCode(query.getWavePickingCode());
        deliveryDistributionDTO.setGroupCode(UserUtil.getBranchCode());
//        deliveryDistributionDTO.setInventoryCode(query.getInventoryCode());
        deliveryDistributionDTO.setOldInventoryCode(query.getOldInventoryCode());
        deliveryDistributionDTO.setPageSize(NumConst.NUM_NINETY_NINE_THOUSAND_NINE_HUNDRED_NINETY_NINE);
        List<DeliveryDistributionVO> deliveryDistributionVOList = this.queryList(deliveryDistributionDTO);
        List<Delivery> deliveryList = iDeliveryService.list(new QueryWrapper<Delivery>().lambda()
                .eq(Delivery::getGroupCode,UserUtil.getBranchCode())
                .eq(Delivery::getWavePickingCode, query.getWavePickingCode()));
        Map<String, Delivery> deliveryMap = deliveryList.stream().collect(Collectors.toMap(Delivery::getCode, e->e));

        for (DeliveryDistributionVO deliveryDistributionVO : deliveryDistributionVOList) {
            Delivery delivery = deliveryMap.get(deliveryDistributionVO.getDeliveryCode());
            if(null!=delivery) {
                deliveryDistributionVO.setDeliveryOrderCode(delivery.getDeliveryOrderCode());
                deliveryDistributionVO.setLogisticsName(LogisticsUtils.translate(delivery.getLogisticsCode()));
                deliveryDistributionVO.setCustomerName(customerCache.translate(delivery.getCustomerCode()));
                deliveryDistributionVO.setGoodsName(goodsCache.translate(deliveryDistributionVO.getGoodsCode()));
            }
        }
        return deliveryDistributionVOList;
    }

    /**
     * 根据波次号获取对应订单分配单关联的库存托盘号
     *
     * @param wavePickingCode
     * @return
     */
    @Override
    public List<String> getContainerCodesForOutCheck(String wavePickingCode,String groupCode) {
        List<DeliveryDistribution> distributions = this.baseMapper.selectList(new LambdaQueryWrapper<DeliveryDistribution>().select(DeliveryDistribution::getInventoryContainerBarCode)
                .eq(DeliveryDistribution::getGroupCode,groupCode)
                .eq(DeliveryDistribution::getWavePickingCode, wavePickingCode)
                .eq(DeliveryDistribution::getDeleted, NUM_ZERO)
                .ne(DeliveryDistribution::getInventoryContainerBarCode, StrUtil.EMPTY)
                .apply(" outbound_quantity = plan_quantity"));
        List<String> codes = distributions.stream().map(e->e.getInventoryContainerBarCode()).collect(Collectors.toList());
        return codes;
    }

    /**
     * 根据订单号集合获取对应订单分配单关联的库存托盘号
     * @param deliveryCodes
     * @return
     */
    @Override
    public List<String> getContainerCodesForOutCheck(List<String> deliveryCodes,String groupCode){
        List<DeliveryDistribution> distributions = this.baseMapper.selectList(new LambdaQueryWrapper<DeliveryDistribution>().select(DeliveryDistribution::getInventoryContainerBarCode)
                .eq(DeliveryDistribution::getGroupCode,groupCode)
                .eq(DeliveryDistribution::getDeliveryCode, deliveryCodes)
                .ne(DeliveryDistribution::getInventoryContainerBarCode, StrUtil.EMPTY)
                .apply(" outbound_quantity = plan_quantity"));
        List<String> codes = distributions.stream().map(e->e.getInventoryContainerBarCode()).collect(Collectors.toList());
        return codes;
    }
    /**
     * 处理订单完全缺货的逻辑
     * @param wavePickingCode 波次号
     * @param operationType 操作类型
     */
    @Override
    public void handleWholeStockOutDelivery(String wavePickingCode,String operationType) {
        String branchCode = UserUtil.getBranchCode();
        //查询完全缺货的订单
        List<Delivery> deliveryList = iDeliveryService.list(new QueryWrapper<Delivery>().lambda().eq(Delivery::getWavePickingCode, wavePickingCode)
                .eq(Delivery::getGroupCode,branchCode)
                .apply("total_num=recheck_refund_quantity+pick_stock_out_num").eq(Delivery::getDeleted, NUM_ZERO));
        if (IterUtil.isEmpty(deliveryList)) {
            return;
        }

        //抹除订单、订单明细的波次号等信息、删除分配单信息
        for (Delivery delivery : deliveryList) {
            iDeliveryService.update(new UpdateWrapper<Delivery>().lambda().eq(Delivery::getCode, delivery.getCode()).eq(Delivery::getGroupCode,branchCode).set(Delivery::getPickNum, BigDecimal.ZERO).set(Delivery::getWavePickingCode, StrUtil.EMPTY).set(Delivery::getPickStockOutNum,BigDecimal.ZERO).set(Delivery::getStatus,DeliveryStatusEnum.UN_DISTRIBUTION.getValue()).set(Delivery::getRecheckQuantity,BigDecimal.ZERO).set(Delivery::getRecheckRefundQuantity,BigDecimal.ZERO).set(Delivery::getDistributionNum,BigDecimal.ZERO));
            iDeliveryItemService.update(new UpdateWrapper<DeliveryItem>().lambda().eq(DeliveryItem::getGroupCode,branchCode).eq(DeliveryItem::getDeliveryCode, delivery.getCode()).eq(DeliveryItem::getGroupCode,UserUtil.getBranchCode()).set(DeliveryItem::getPickingQuantity, BigDecimal.ZERO).set(DeliveryItem::getPickStockOutNum, BigDecimal.ZERO).set(DeliveryItem::getWavePickingCode,StrUtil.EMPTY).set(DeliveryItem::getDistributionQuantity,BigDecimal.ZERO).set(DeliveryItem::getStatus,DeliveryStatusEnum.ADD.getValue()).set(DeliveryItem::getRecheckQuantity,BigDecimal.ZERO).set(DeliveryItem::getDistributionQuantity,BigDecimal.ZERO));
            this.remove(new QueryWrapper<DeliveryDistribution>().lambda().eq(DeliveryDistribution::getGroupCode,branchCode).eq(DeliveryDistribution::getDeliveryCode, delivery.getCode()).eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode()));
        }

        //调整出库单的计划数量
        if (PropertyConst.OUT_BOUND.equals(operationType)) {
            List<Delivery> deliveries = iDeliveryService.list(new UpdateWrapper<Delivery>().lambda().eq(Delivery::getWavePickingCode, wavePickingCode).eq(Delivery::getGroupCode,branchCode));
            BigDecimal deliveryPlanQuantity = deliveries.stream().map(Delivery::getTotalNum).reduce(BigDecimal.ZERO, BigDecimal::add);
            iOutboundService.update(new UpdateWrapper<Outbound>().lambda().eq(Outbound::getWavePickingCode, wavePickingCode).set(Outbound::getDeliveryPlanQuantity, deliveryPlanQuantity).eq(Outbound::getGroupCode,branchCode));
        }
    }

    /**
     * 更新拣货单状态
     * @param wavePickingCode 波次号
     */
    private void updatePickingStatus(String wavePickingCode) {
        Picking picking = iPickingService.getOne(new QueryWrapper<Picking>().lambda().eq(Picking::getWavePickingCode, wavePickingCode).eq(Picking::getGroupCode,UserUtil.getBranchCode()));
        BigDecimal totalQuantity = picking.getPickingQuantity().add(picking.getStockoutQuantity());
        BigDecimal planQuantity = picking.getPlanQuantity();
        if (planQuantity.compareTo(totalQuantity) > NUM_ZERO && planQuantity.compareTo(BigDecimal.ZERO) > NUM_ZERO) {
            iPickingService.update(new UpdateWrapper<Picking>().lambda().eq(Picking::getWavePickingCode, wavePickingCode).set(Picking::getStatus, PickingStatusEnum.PICKING.getValue()).eq(Picking::getGroupCode,UserUtil.getBranchCode()));
        }
    }

    /**
     * 更新出库单状态
     * @param wavePickingCode 波次号
     */
    private void updateOutboundStatus(String wavePickingCode) {
        Outbound outbound = iOutboundService.getOne(new QueryWrapper<Outbound>().lambda().eq(Outbound::getWavePickingCode, wavePickingCode).eq(Outbound::getGroupCode,UserUtil.getBranchCode()).eq(Outbound::getDeleted, NUM_ZERO));
        BigDecimal totalQuantity = outbound.getRecheckQuantity().add(outbound.getRecheckRefundQuantity());
        BigDecimal planQuantity = outbound.getPlanQuantity();
        if (planQuantity.compareTo(totalQuantity) > NUM_ZERO && planQuantity.compareTo(BigDecimal.ZERO) > NUM_ZERO) {
            iOutboundService.update(new UpdateWrapper<Outbound>().lambda().eq(Outbound::getWavePickingCode,wavePickingCode).set(Outbound::getStatus, OutboundStatusEnum.RECHECKING.getValue()).eq(Outbound::getGroupCode,UserUtil.getBranchCode()));
        }
    }

    /***
     * @description
     * 根据订单号，更新分配单拣货数量
     * @author xuyang
     * @date 2020/10/23 14:10
     * @param deliveryCode:
     * @param recheckQuantity:
     * @param oldInventoryCode:
     **/
    @Override
    public int updateRechekQuantity(String deliveryCode,String oldInventoryCode, BigDecimal recheckQuantity,BigDecimal recheckRefundQuantity,String groupCode) {
        return this.baseMapper.updateRechekQuantity(deliveryCode, oldInventoryCode,recheckQuantity,recheckRefundQuantity,groupCode);
    }

    private List<Inventory> matchPrepackagedInv(List<DeliveryItem> deliveryItems,Delivery delivery) {
        List<DeliveryItem> sortedItem = deliveryItems.stream().sorted(Comparator.comparing(DeliveryItem::getGoodCode))
                .collect(Collectors.toList());
        DeliveryItem firstItem = sortedItem.get(NUM_ZERO);
        //生成快速匹配号
        StringBuilder sb = new StringBuilder();
        sortedItem.stream().forEach(e -> {
            sb.append(e.getGoodCode() + "_" + e.getTotalNum() + "#");
        });
        sb.replace(sb.length() - 1, sb.length(), "");
        String fastMatching = sb.toString();
        //获取预打包临时库位
        Location location = locationService.getOne(new LambdaQueryWrapper<Location>()
                .eq(Location::getGroupCode,UserUtil.getBranchCode())
                .eq(Location::getWarehouseCode, delivery.getWarehouseCode())
                .eq(Location::getSerialNumber, CommonConst.YDKW));
        List<Inventory> invList =  iInventoryService.list(new LambdaQueryWrapper<Inventory>()
                .eq(Inventory::getGroupCode,UserUtil.getBranchCode())
                .eq(Inventory::getWarehouseCode, delivery.getWarehouseCode())
                .eq(Inventory::getShipmentCode, delivery.getShipmentCode())
                .eq(Inventory::getLocation, location.getCode())
                .eq(Inventory::getFastMatching, fastMatching)
                .apply("quantity > use_quantity"));
        //判断预打包库存是否充足
        List<Inventory> filterInv = invList.stream().filter(e -> e.getGoodCode().equals(firstItem.getGoodCode())
                && (e.getQuantity().subtract(e.getUseQuantity()).compareTo(firstItem.getTotalNum()) >= 0))
                .collect(Collectors.toList());
        if (IterUtil.isEmpty(filterInv)) {
            return filterInv;
        } else {
            return invList;
        }
    }

    private BigDecimal prepackagedInvDistribute(List<Inventory> prepackagedInvList,List<DeliveryItem> deliveryItems,
                                            BigDecimal totalNewLockQuantity,Delivery delivery) {
        for(DeliveryItem deliveryItem: deliveryItems){

            // 剩余待分配数量就是明细的总数量
            BigDecimal remainQuantity = deliveryItem.getTotalNum();
            // 库存可用数量
            BigDecimal usefulQuantity;
            // 待锁定数量
            BigDecimal lockQuantity;
            // 明细新增待锁定数量
            BigDecimal totalItemNewLockQuantity = BigDecimal.ZERO;
            //过滤掉其他商品
            List<Inventory> filterPrepackagedInvList = prepackagedInvList.stream().filter(info -> info.getGoodCode().equals(deliveryItem.getGoodCode()))
                    .collect(Collectors.toList());
            List<UsefulInventoryVO> inventories = filterPrepackagedInvList.stream().map(info -> {
                UsefulInventoryVO inventoryVO = new UsefulInventoryVO();
                BeanUtil.copyProperties(info, inventoryVO);
                return inventoryVO;
            }).collect(Collectors.toList());
            DeliveryDistribution distribution;
            Inventory distributeInventory = new Inventory();
            Inventory tempInventory;
            // 遍历获取明细，根据明细的总数-分配数量>0的即需要分配的
            if (IterUtil.isNotEmpty(inventories)) {
                for(UsefulInventoryVO inventory: inventories){
                    usefulQuantity = inventory.getQuantity().subtract(inventory.getUseQuantity());
                    lockQuantity = usefulQuantity.compareTo(remainQuantity)>0?remainQuantity:usefulQuantity;
                    // 更新主子表新锁定数量
                    totalItemNewLockQuantity = totalItemNewLockQuantity.add(lockQuantity);
                    totalNewLockQuantity = totalNewLockQuantity.add(lockQuantity);

                    // 插入或更新分配表
                    distribution = insertOrUpdateDistribution(inventory, deliveryItem, lockQuantity);

                    // 减去库存
                    reduceInventory(distribution, deliveryItem);

                    BeanUtil.copyProperties(inventory, distributeInventory);
                    // 增加临时库存
                    tempInventory = saveDeliveryTempInventory(distribution, delivery, deliveryItem, distributeInventory);

                    // 临时库位中的库存作业状态改为工作中，避免其他操作使用
                    iInventoryService.setTempInvJobStatusWorking(tempInventory.getCode());

                    // 记录库存变动日志， 原库存减少，临时库存增加
                    iInventoryRecordService.insertRecord(distributeInventory, delivery.getCode(), distribution.getDistributionQuantity().negate(), InventoryRecordTypeEnum.PICK.getValue());
                    iInventoryRecordService.insertRecord(tempInventory, delivery.getCode(), distribution.getDistributionQuantity(), InventoryRecordTypeEnum.PICK.getValue());

                    // 需要回填发货分配的库存，将库存编码指向临时库存
                    update(new UpdateWrapper<DeliveryDistribution>().lambda()
                            .eq(DeliveryDistribution::getGroupCode,UserUtil.getBranchCode())
                            .eq(DeliveryDistribution::getCode, distribution.getCode())
                            .set(DeliveryDistribution::getInventoryCode, tempInventory.getCode())
                            .set(DeliveryDistribution::getOldInventoryCode,inventory.getCode())
                    );

                    // 更新剩余数量
                    remainQuantity = remainQuantity.subtract(lockQuantity);

                    // 剩余分配数量为0，则说明完成分配，提前退出循环
                    if(remainQuantity.compareTo(BigDecimal.ZERO) == 0){
                        break;
                    }
                }
            }

            // 更新明细的分配数量
            if(totalItemNewLockQuantity.compareTo(BigDecimal.ZERO) > 0) {
                DeliveryItemDTO deliveryItemDTO = new DeliveryItemDTO();
                deliveryItemDTO.setCode(deliveryItem.getCode());
                deliveryItemDTO.setDistributionQuantity(totalItemNewLockQuantity);
                iDeliveryItemService.adjustDistributionQuantity(deliveryItemDTO);
            }
        }
        return totalNewLockQuantity;
    }


    /**
     * 更新拣货数量
     *
     * @param wavePickingCode
     * @return int
     * @author liuxr
     * @date 2021/12/10 12:57
     */
    @Override
    public int updatePickingQuantityStatusByWavePickingCode(String wavePickingCode,String status,String groupCode) {
        return baseMapper.updatePickingQuantityStatusByWavePickingCode(wavePickingCode,status,groupCode);
    }

    /***
     * @description
     * 根据订单明细号，更新分配单复核数量
     * @author rfwang
     * @date 2022年3月16日
     * @param deliveryCode:
     * @param recheckQuantity:
     **/
    @Override
    public int updateRechekQuantityByItem(String deliveryCode, String deliveryItemCode, BigDecimal recheckQuantity, String groupCode){
        List<DeliveryDistribution> deliveryDistributions = this.list(new LambdaQueryWrapper<DeliveryDistribution>().eq(DeliveryDistribution::getDeliveryItemCode, deliveryItemCode));
        BigDecimal remainRecheckQuantity = recheckQuantity;
        int updateNum = 0;
        //一个出库明细对应多个出库登记的逻辑
        if (deliveryDistributions.size() > 1) {
            List<String> statuses = new ArrayList<>(Arrays.asList(DeliveryStatusEnum.UN_RECHECK.getValue(), DeliveryStatusEnum.RECHECKING.getValue()));
            //获取待复核和复核中的复核登记信息
            List<DeliveryDistribution> DeliveryDistributionList = deliveryDistributions.stream().filter(e -> statuses.contains(e.getStatus())).collect(Collectors.toList());
            for (DeliveryDistribution deliveryDistribution : DeliveryDistributionList) {
                BigDecimal singleRecheckQuantity = remainRecheckQuantity.compareTo(deliveryDistribution.getRecheckQuantity()) >= 0 ? deliveryDistribution.getPickingQuantity() : remainRecheckQuantity;
                remainRecheckQuantity = remainRecheckQuantity.subtract(recheckQuantity);
                //更新明细复核数量
                updateNum += this.updateRechekQuantity(deliveryCode,deliveryDistribution.getOldInventoryCode(),singleRecheckQuantity,BigDecimal.ZERO,groupCode);
                if (remainRecheckQuantity.compareTo(BigDecimal.ZERO) == 0) {
                    return updateNum;
                }
            }

        }
        return this.updateRechekQuantity(deliveryCode,deliveryDistributions.get(NumConst.NUM_ZERO).getOldInventoryCode(),remainRecheckQuantity,BigDecimal.ZERO,groupCode);
    }
}
